﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Data;

namespace UE.SharePoint.ImportExport.BLL.SharePoint
{
    /// <summary>
    /// this is used to reader sharepoint data
    /// </summary>
    public class SPListReader : IReader
    {
        private Setting _setting; 

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="setting"></param>
        public SPListReader(Setting setting)
        {
            _setting = setting; 
        }

        /// <summary>
        /// 
        /// </summary>
        public Setting Setting
        {
            get { return _setting; }
            set { _setting = value; }
        } 

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public DataTable GetData()
        {
            DataTable result = new DataTable();
            SPList spList = Setting.SPList;
            SPQuery spQuery = new SPQuery();
            Column[] schemaColumns = LoadColumns();

            StringBuilder spQueryFields = new StringBuilder();
            foreach (Column field in schemaColumns)
            {
                spQueryFields.AppendFormat("<FieldRef Name='{0}'/>", field.InternalName);
            }
            spQuery.ViewFields = spQueryFields.ToString();

            if (!string.IsNullOrEmpty(Setting.Query))
            {
                spQuery.Query = Setting.Query;
            }

            SPListItemCollectionPosition spListItemCollectionPosition = null;
            result = spList.GetDataTable(spQuery, SPListGetDataTableOptions.None, out spListItemCollectionPosition);

            if (null != result)
            {
                foreach (DataColumn resultColumn in result.Columns)
                {
                    Column schemaColumn = schemaColumns.FirstOrDefault(e => e.InternalName == resultColumn.ColumnName);
                    if (null != schemaColumn)
                    {
                        resultColumn.ColumnName = schemaColumn.Name;
                    }
                }
            }

            return result;
        } 

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns> 
        public Column[] LoadColumns()
        {
            List<Column> columns = new List<Column>();
            SPList spList = Setting.SPList;

            for (int i = 0; i < spList.Fields.Count; i++)
            {
                SPField spField = spList.Fields[i];
                SPFieldLookup fldLookup = spField as SPFieldLookup;
                bool bCountRelated = fldLookup != null && fldLookup.CountRelated;
                bool isDependentLookup = fldLookup != null && fldLookup.IsDependentLookup;
                bool bMcolLookup = fldLookup != null && fldLookup.IsDependentLookup && fldLookup.LookupList != "Docs";

                SPFieldType t = spField.Type;
                if (t == SPFieldType.Computed ||
                    t == SPFieldType.File ||
                    t == SPFieldType.Recurrence ||
                    t == SPFieldType.CrossProjectLink ||
                    t == SPFieldType.AllDayEvent)
                {
                    continue;
                }

                if (!spField.Reorderable &&
                    !bCountRelated &&
                    //!(spField.ReadOnlyField && spField.Type == SPFieldType.User) &&
                    !(bMcolLookup && !spField.Hidden) &&
                    !spList.HasExternalDataSource)
                {
                    continue;
                }

                if (spField.ShowInListSettings == false)
                {
                    continue;
                }

                if (!Setting.IsContainAdditionalColumn && isDependentLookup)
                {
                    continue;
                }

                Column column = new Column(spList.Fields[i].Title, spList.Fields[i].InternalName);
                if (columns.Any(e => e.Name.Equals(column.Name)))
                {
                    column.Name = column.Name + "(" + column.InternalName + ")";
                }

                columns.Add(column);
            }

            return columns.ToArray();
        }

        public string[] LoadTables()
        {
            throw new NotImplementedException();
        }
    }
}
